﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufBase.h"
#include "GnufImpl.h"
#include "GnufModuleManager.h"
#include "GnufItemEvents.h"
#include "GnufPushButton.h"
#include "GnufArrangementAreaContent.h"

namespace gnuf {
    class QtModuleBar;
    class Toolbar;
    class DropDownButton;
    class ModuleBarDropDownButton;
/*
        <------ Frontward
                       Backward ------>
    +-------------------------------------+
    | +---------+ +---------+ +---------+ |             Downward ---------+
    | | Module  | | Module  | | Module  | | Module Bar                    |
    | | Button  | | Button  | | Button  | |                     <---+     |
    | +---------+ +---------+ +---------+ |                         |     |
    +-------------------------------------+-----------------+       |     |
                                          |[ ] Module Entry |    Upward   |
                                   Module |[ ] Module Entry |             v
                                 Dropdown |[ ] Module Entry |
                                     Menu |[ ] Module Entry |
                                          |[ ] Module Entry |
                                          +-----------------+
*/
    namespace impl { class GNUF_IMPL_CLASS(ModuleBar); }
    class GNUF_BASE_EXPORT ModuleBar final
    {
        GNUF_IMPL_USE(ModuleBar);
    public:
        explicit ModuleBar();
        ~ModuleBar();

        static ModuleBar* get();

        /// \brief Show the module bar.
        void show();

        /// \brief Hide the module bar.
        void hide();

        /// \return Return the visibility of module bar.
        bool isVisible();

        /// \set the caption text of module bar from block.
        void setCaption(const std::wstring&);

        /// \return the caption text of module bar from block.
        std::wstring getCaption();

        /// \set the count of show text of module bar.
        void setTextCount(int count);

    };

    /// \brief 模块按钮
    class ModuleButton final : public PushButton
    {
    public:
        /// \brief 按钮的类型
        enum class EButtonType :std::uint8_t
        {
            eBlock,             ///< button on Block
            eDropDownBoard      ///< button on DropDownBoard
        };
        ModuleButton(Item* parent);
        virtual ~ModuleButton() {};
        void setButtonType(EButtonType container);
        EButtonType buttonType() const { return m_buttonType; }
        /// \brief 按钮附带的Module信息
        void setModuleGuid(const std::wstring guid) { m_moduleGuid = guid; }
        const std::wstring& moduleGuid() { return m_moduleGuid; }

        /// \brief 按钮是否为下拉菜单的“更多”
        bool isMoreButton() const { return m_bIsMoreButton; };
        void setAsMoreButton(bool bAs) { m_bIsMoreButton = bAs; }

    private:
        std::wstring m_moduleGuid;
        bool m_bIsMoreButton = false;
        EButtonType m_buttonType = EButtonType::eDropDownBoard;
    };


    class ModuleBarBlock final
    {
        CANNOT_COPY_OR_ASSIGN(ModuleBarBlock)
    public:
        typedef typename std::vector<ModuleButton*> Buttons;
        explicit ModuleBarBlock(impl::GNUF_IMPL_CLASS(ModuleBar) * moduleBar);
        ~ModuleBarBlock() {};

        ModuleButton* addButton();
        inline const Buttons& getButtons() const
        {
            return m_moduleButtons;
        }
        inline Buttons& getButtons()
        {
            return m_moduleButtons;
        }

        int& rSpacing() { return m_spacing; }
        const int spacing() const { return m_spacing; }

        Margin& rMargin() { return m_margin; }
        const Margin& margin() const { return m_margin; }

        int& rModuleButtonWidth() { return m_moduleButtonWidth; }
        const int moduleButtonWidth() const { return m_moduleButtonWidth; }

        void setIconStyle(bool bBigIcon);

        int blockWidthForCount(int buttonCount) const;

        const Toolbar* toolbar() const { return m_toolbar.get(); }
        Toolbar* toolbar() { return m_toolbar.get(); }
        inline std::wstring getCaption() const { return m_caption; }
        inline void setCaption(const std::wstring& caption) { m_caption = caption; }
        inline const ButtonAppearanceSetting* buttonAppearanceSetting() const;

    private:
        std::wstring m_caption;
        gcmp::OwnerPtr<Toolbar> m_toolbar;
        Buttons m_moduleButtons;
        int m_spacing;
        gnuf::Margin m_margin;
        int m_moduleButtonWidth;
        bool m_bBigIcon = true;
    };
}
namespace gnuf {
namespace impl {
    class GNUF_IMPL_CLASS(ModuleBar) final 
        : public IModuleBar
        , public ArrangementAreaContent
        , public IItemEventHandler
    {
        GNUF_IMPL_USED_BY(ModuleBar);
    public:
        typedef typename std::vector<const Module*> Modules;
        GNUF_IMPL_CLASS(ModuleBar)(ModuleBar* moduleBar);
        ~GNUF_IMPL_CLASS(ModuleBar)();

        void initialize();

        virtual QWidget* qtWidget() override;

        void show();
        void hide();

        bool isVisible();

        void setCaption(const std::wstring&);
        std::wstring getCaption() const;
        
        /// \brief 在ModuleBar上显示的Modules，
        const Modules& filteredModules() const;

        ModuleBarBlock* moduleBarBlock() { return m_moduleBarBlock.get(); };
        ModuleBarDropDownButton* moduleBarDropDownButton() { return m_moduleBarDropDownButton.get(); }

        const AppearanceSetting* appearanceSetting() const;

        int currentModuleBarWidth();

        QtModuleBar* qtItem() { return m_qtModuleBar; }
        void setQtItem(QtModuleBar* qtItem) { m_qtModuleBar = qtItem; }

        // ToolBar图标大小样式
        void refreshIcon(bool bBig);

    protected:
        // Inherits from impl::IModuleBar...
        virtual void onAdded            (const Module * pNewModule) override;
        virtual void onPreRemoved       (const Module * pModule) override;
        virtual void onActivationChanged(const Module * pOldActiveModule,
                                         const Module * pNewActiveModule) override;
    protected:
        // Inherits from ArrangementAreaContent
        virtual void onPostConnectedWithArrangementArea() override;
        virtual void onPreDisconnectedFromArrangementArea() override;
        virtual void onPostAbilityChanged() override;
        virtual void onPostGeometryChanged() override;
        virtual void onPostVisibilityChanged() override {};
        virtual void onEvent(ArrangementAreaEvent* evt) override;

        // Inherits from IItemEventHandler
        virtual void onClicked(Item* item) override;
        virtual void onCurrentIndexChanged(DropDownBoard* pDropDown, int index, Item* pItem) override;
        virtual void onHovered(Item* item, bool hovered, void* qtWgt) override;

        void refreshAppearance();
        void updateModuleBarBlock();
        void updateModuleBarDropDown();
        bool onShouldToShowModuleBar();
    private:
        // 大小图标样式切换，刷新Button的样式（如：BodorWidth）
        void updateModuleBarBlockCustomizeSetting();
        // 重新调整ModuleBar的宽度，避免大图标切换小图标后，右侧留白太大
        void adjustWidth();

    private:
        QtModuleBar* m_qtModuleBar;
        Modules m_filteredModules;
        const Module* m_fixedModule;
        gcmp::OwnerPtr<ModuleBarBlock> m_moduleBarBlock;
        gcmp::OwnerPtr<ModuleBarDropDownButton> m_moduleBarDropDownButton;
        bool m_bBigIcon = true;
        int m_textCount = 4;
    };
} }
